package com.yangsir.mysite.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yangsir.mysite.Dto.ArticleDto;
import com.yangsir.mysite.Dto.ArticleUserDto;
import com.yangsir.mysite.common.R;
import com.yangsir.mysite.mapper.ArticleMapper;
import com.yangsir.mysite.mapper.CategoryMapper;
import com.yangsir.mysite.mapper.CommentMapper;
import com.yangsir.mysite.mapper.TagMapper;
import com.yangsir.mysite.pojo.Article;
import com.yangsir.mysite.pojo.Comment;
import com.yangsir.mysite.pojo.Tag;
import com.yangsir.mysite.pojo.User;
import com.yangsir.mysite.service.ArticleService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yf
 * @description 针对表【article(文章)】的数据库操作Service实现
 * @createDate 2024-06-22 16:55:16
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article>
        implements ArticleService {
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private TagMapper tagMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private CommentMapper commentMapper;


    /**
     * 保存前端传来的文章
     *
     * @param article
     * @return
     */
    @Override
    @Transactional
    public R<String> saveArticle(Article article) {
        // 雪花算法
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        if (articleMapper.insert(article) != 1) {
            return R.error("保存失败");
        }
        // 更新Category文章数量
        if (article.getCategoryId() != null) {
            categoryMapper.addArticleCount(article.getCategoryId());
        }

        List<Tag> tags = new ArrayList<>();
        if (article.getTags() != null) {
            String[] split = article.getTags().split(",");
            tags = Arrays.stream(split)
                    .filter(s -> !s.isEmpty()) // 过滤掉空字符串
                    .map(t -> {
                        Tag tag = new Tag();
                        tag.setId(snowflake.nextId());
                        tag.setUserId(article.getUserId());
                        tag.setType(article.getType());
                        tag.setCategoryId(article.getCategoryId());
                        tag.setTagName(t.trim()); // 去除标签两边的空白字符
                        tag.setCreateTime(LocalDateTime.now());
                        tag.setUpdateTime(LocalDateTime.now());
                        return tag;
                    }).collect(Collectors.toList());
        }
        // 批量插入,不报错
        for (Tag tag : tags) {
            tagMapper.insertTags(tag);
        }

        return R.success("保存成功");
    }

    /**
     * 获取文章详情
     *
     * @param id
     * @return
     */
    @Override
    public R<Article> getOneArticle(Long id) {
        Article article = articleMapper.selectById(id);
        if (article == null) {
            return R.error("暂无本篇文章");
        }
        article.setHot(article.getHot() + 1);
        articleMapper.updateById(article);
        return R.success(article, "文章获取成功");
    }

    /**
     * 分页查询文章
     *
     * @param page
     * @param pageSize
     * @param type
     * @return
     */
    @Override
    public R<Page> pageQuery(Integer page, Integer pageSize, Integer type, Long categoryId, String clickedtags) {
        Page<Article> pageinfo = new Page(page, pageSize);
        Page<ArticleDto> pageInfoDto = new Page(page, pageSize);
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getType, type);
        // 如果有 归档分类 信息就 添加查询条件
        if (categoryId != null) {
            queryWrapper.eq(Article::getCategoryId, categoryId);
        }
        // 如果有 标签信息 就 添加查询条件
        if (clickedtags != null) {
            String[] split = clickedtags.split(",");
            StringBuilder orConditions = new StringBuilder();
            for (int i = 0; i < split.length; i++) {
                if (orConditions.length() > 0) {
                    orConditions.append(" OR ");
                }
                orConditions.append("tags LIKE '%").append(split[i]).append("%'");
            }
            String orSql = "(" + orConditions + ")";
            queryWrapper.apply(orSql);
        }
        queryWrapper.orderByDesc(Article::getCreateTime);
        articleMapper.selectPage(pageinfo, queryWrapper);
        if (pageinfo.getRecords().size() == 0) {
            return R.success("暂无数据");
        }
        return R.success(this.copyPage(pageinfo, pageInfoDto), "文章已获取");
    }

    // 拷贝分页信息到Dto
    public Page<ArticleDto> copyPage(Page<Article> pageinfo, Page<ArticleDto> pageInfoDto) {
        BeanUtils.copyProperties(pageinfo, pageInfoDto, "records");
        List<Article> articles = pageinfo.getRecords();
        List<ArticleDto> articleDtos = articles.stream().map(article -> {
            ArticleDto articleDto = new ArticleDto();
            BeanUtils.copyProperties(article, articleDto);
            articleDto.setTagsAry(article.getTags().split(","));
            return articleDto;
        }).collect(Collectors.toList());
        pageInfoDto.setRecords(articleDtos);
        return pageInfoDto;
    }

    /**
     * 根据用户获取文章(作者及管理员)
     *
     * @param
     * @return
     */
    @Override
    public R<List<ArticleUserDto>> getArticlesByUserId(HttpServletRequest httpServletRequest) {
        User user = (User) httpServletRequest.getSession().getAttribute("user");
        if (user.getUserRole() == 1) {// 作者
            List<ArticleUserDto> articleUserDtos = articleMapper.selectArticleWithUser(user.getId());
            if (articleUserDtos.size() == 0) {
                return R.success(articleUserDtos, "无创作文章");
            }
            return R.success(articleUserDtos, "文章已获取");
        } else if (user.getUserRole() == 2) {// 管理员
            List<ArticleUserDto> articleUserDtos = articleMapper.selectAllArticleWithUser();
            if (articleUserDtos.size() == 0) {
                return R.success(articleUserDtos, "无创作文章");
            }
            return R.success(articleUserDtos, "文章已获取");
        } else if (user.getUserRole() == 0) {
            return R.error("权限不足");
        }
        return R.error("发生未知异常");
    }

    /**
     * 根据关键字搜索文章(作者及管理员)
     *
     * @param str
     * @return
     */
    @Override
    public R<List<ArticleUserDto>> getArticlesByStr(String str) {
        List<ArticleUserDto> articleUserDtos = articleMapper.selectArticleWithUserLikeStr(str);
        return R.success(articleUserDtos, "搜索成功");
    }

    /**
     * 删除文章(作者及管理员)
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public R<String> deleteArticle(Long id) {
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        commentMapper.delete(queryWrapper.eq(Comment::getArticleId, id));
        if (articleMapper.deleteById(id) == 1) {
            Article article = articleMapper.selectById(id);
            if (article.getCategoryId() != null) {
                categoryMapper.reduceArticleCount(article.getCategoryId());

            }
            return R.success("已删除");
        }
        return R.error("删除失败");
    }

    /**
     * 设置置顶文章管理员
     *
     * @param article
     * @return
     */
    @Override
    public R<String> topArticle(Article article) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getIsTop, 1);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        if (article.getIsTop() == 1 && articles.size() >= 5) {
            return R.error("置顶文章已达上限");
        }
        if (articleMapper.updateById(article) == 1) {
            return R.success("置顶已更新");
        }
        return R.success("置顶已更新");
    }

    /**
     * 获取置顶文章
     *
     * @return
     */
    @Override
    public List<Article> getTopArticle() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getIsTop, 1);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        return articles;
    }

    /**
     * 根据分类获取文章
     *
     * @param type
     * @param categoryId
     * @return
     */
    @Override
    public R<List<ArticleUserDto>> getArticlesByTypeOrCategory(Integer type, Long categoryId, HttpServletRequest httpServletRequest) {
        User user = (User) httpServletRequest.getSession().getAttribute("user");
        if (categoryId == null) {
            if (user.getUserRole() == 2) {
                return R.success(articleMapper.selectAllArticleWithUserByType(type), "文章已获取");
            } else if (user.getUserRole() == 1) {
                return R.success(articleMapper.selectArticleWithUserByType(type, user.getId()), "文章已获取");
            }
        }
        if (type == 2) {
            if (user.getUserRole() == 2) {
                return R.success(articleMapper.selectAllArticleWithUserByCategory(categoryId), "文章已获取");
            } else if (user.getUserRole() == 1) {
                return R.success(articleMapper.selectArticleWithUserByCategory(categoryId, user.getId()), "文章已获取");
            }
        }
        return R.error("权限不足");
    }

    /**
     * 根据分类获取文章
     *
     * @param categoryId
     * @return
     */
    @Override
    public R<List<Article>> getArticlesByCategory(Long categoryId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getCategoryId, categoryId);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        return R.success(articles, "文章已获取");
    }


}




